package com.netease.demo.shortvideo.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;

import com.netease.demo.shortvideo.DemoCache;
import com.netease.demo.shortvideo.R;
import com.netease.demo.shortvideo.adapter.VideoAdapter;
import com.netease.demo.shortvideo.config.Preferences;
import com.netease.demo.shortvideo.model.VideoItem;
import com.netease.demo.shortvideo.server.DemoServerHttpClient;
import com.netease.demo.shortvideo.server.entity.AddVideoResponseEntity;
import com.netease.demo.shortvideo.server.entity.VideoInfoEntity;
import com.netease.demo.shortvideo.uploader.UploadController;
import com.netease.demo.shortvideo.uploader.constant.UploadState;
import com.netease.nim.uikit.LoginSyncDataStatusObserver;
import com.netease.nim.uikit.NimUIKit;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialog;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseFetchLoadAdapter;
import com.netease.nim.uikit.common.ui.recyclerview.listener.OnItemClickListener;
import com.netease.nim.uikit.common.ui.recyclerview.loadmore.MsgListFetchLoadMoreView;
import com.netease.nim.uikit.common.util.sys.NetworkUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by hzxuwen on 2017/4/5.
 */

public class MainActivity extends UI implements View.OnClickListener, UploadController.UploadUi, VideoAdapter.EventListener {
    // constant
    private static final int VIDEO_LIMIT = 10;

    // view
    private ImageView takeVideoImage; // 开始拍摄按钮
    private RecyclerView videoListView; // 视频列表控件

    // data
    private int videoCount; // 已经上传服务器的视频数量
    private VideoAdapter videoAdapter;
    private List<VideoItem> items; // 视频item列表
    private UploadController uploadController; // 上传视频控制器
    private HashMap<Long, VideoInfoEntity> videosFromServer;

    private interface FetchVideoListener {
        void onFetchVideoDone();
    }

    public static void start(Context context) {
        Intent intent = new Intent(context, MainActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        findViews();
        setListener();
        initData();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        uploadController.detachUi(this);
    }

    private void findViews() {
        findView(R.id.logout_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showLogoutConfirm();
            }
        });

        takeVideoImage = findView(R.id.take_video_image);
        videoListView = findView(R.id.video_list);

        // adapter
        items = new ArrayList<>();
        videoAdapter = new VideoAdapter(videoListView, R.layout.video_item_layout, items);
        videoAdapter.setEventListener(this);
        videoAdapter.setFetchMoreView(new MsgListFetchLoadMoreView());
        videoAdapter.setOnFetchMoreListener(new BaseFetchLoadAdapter.RequestFetchMoreListener() {
            @Override
            public void onFetchMoreRequested() {
                getVideoList(null);
            }
        });
        videoListView.addOnItemTouchListener(new OnItemClickListener<VideoAdapter>() {
            @Override
            public void onItemClick(VideoAdapter adapter, View view, int position) {
                if (adapter.isPlayLayoutShow(adapter.getItem(position))) {
                    adapter.setPlayLayoutMap(adapter.getItem(position), false);
                } else {
                    adapter.setPlayLayoutMap(adapter.getItem(position), true);
                }
                adapter.notifyItemChanged(position);
            }

            @Override
            public void onItemLongClick(VideoAdapter adapter, View view, int position) {
                onNormalLongClick(position);
            }
        });
        videoListView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        videoListView.setAdapter(videoAdapter);
    }

    private void getVideoList(final FetchVideoListener fetchVideoListener) {
        DemoServerHttpClient.getInstance().videoInfoGet(null, new DemoServerHttpClient.DemoServerHttpCallback<List<VideoInfoEntity>>() {
            @Override
            public void onSuccess(List<VideoInfoEntity> entities) {
                List<VideoInfoEntity> videoInfoEntities = new ArrayList<>();
                List<VideoItem> videoItems = new ArrayList<>();
                for (VideoInfoEntity videoInfoEntity : entities) {
                    if (videosFromServer.containsKey(videoInfoEntity.getVid())) {
                        continue;
                    }
                    videoInfoEntities.add(videoInfoEntity);
                    VideoItem videoItem = new VideoItem();
                    videoItem.setEntity(videoInfoEntity);
                    videoItems.add(videoItem);
                    videosFromServer.put(videoInfoEntity.getVid(), videoInfoEntity);
                }

                // 顶部加载
                if (videoInfoEntities.size() <= 0) {
                    videoAdapter.fetchMoreEnd(true);
                } else {
                    videoCount = videoInfoEntities.size();
                    videoAdapter.fetchMoreComplete(videoListView, videoItems);
                }
                if (fetchVideoListener != null) {
                    fetchVideoListener.onFetchVideoDone();
                }
            }

            @Override
            public void onFailed(int code, String errorMsg) {
            }
        });
    }

    private void setListener() {
        takeVideoImage.setOnClickListener(this);
    }

    private void initData() {
        uploadController = new UploadController();
        uploadController.init(this);
        uploadController.attachUi(this);
        videosFromServer = new HashMap<>();
        getVideoList(null);
    }

    private void showLogoutConfirm() {
        EasyAlertDialogHelper.OnDialogActionListener listener = new EasyAlertDialogHelper.OnDialogActionListener() {

            @Override
            public void doCancelAction() {

            }

            @Override
            public void doOkAction() {
                DemoServerHttpClient.getInstance().logout();
                removeLoginState();
                NimUIKit.clearCache();
                DemoCache.clear();
                LoginSyncDataStatusObserver.getInstance().reset();

                finish();
                LoginActivity.start(MainActivity.this);
            }
        };


        final EasyAlertDialog dialog = EasyAlertDialogHelper.createOkCancelDiolag(this, null,
                "确定退出该账号?", true, listener);
        dialog.show();
    }

    /**
     * 清除登陆状态
     */
    private void removeLoginState() {
        Preferences.saveUserToken("");
        Preferences.saveVodToken("");
    }

    /**
     * 确认是否可以开始拍摄视频
     */
    private void checkTakeVideo() {
        if (videoCount >= VIDEO_LIMIT) {
            showVideoCountDialog();
        } else {
            VideoShootActivity.startActivityForResult(this);
        }
    }

    /**
     * 视频数量已达上限
     */
    private void showVideoCountDialog() {
        EasyAlertDialogHelper.OnDialogActionListener listener = new EasyAlertDialogHelper.OnDialogActionListener() {

            @Override
            public void doCancelAction() {
                // go to delete
            }

            @Override
            public void doOkAction() {
                // go on
                startActivity(new Intent(MainActivity.this, VideoShootActivity.class));
            }
        };
        final EasyAlertDialog dialog = EasyAlertDialogHelper.createOkCancelDiolag(MainActivity.this,
                getString(R.string.video_reach_limit),
                getString(R.string.video_reach_limit_content),
                getString(R.string.continue_shooting), getString(R.string.go_delete_video), true, listener);
        dialog.show();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.take_video_image:
                checkTakeVideo();
                break;
        }
    }

    private void uploadFile(final VideoItem videoItem) {
        if (!NetworkUtil.isNetAvailable(this)) {
            EasyAlertDialogHelper.showOneButtonDiolag(this, null, getString(R.string.network_is_not_available),
                    getString(R.string.iknow), false, null);
            return;
        }

        EasyAlertDialogHelper.OnDialogActionListener listener = new EasyAlertDialogHelper.OnDialogActionListener() {
            @Override
            public void doCancelAction() {

            }

            @Override
            public void doOkAction() {
                getVideoList(new FetchVideoListener() {
                    @Override
                    public void onFetchVideoDone() {
                        if (videoCount > VIDEO_LIMIT) {
                            showVideoCountDialog();
                        } else {
                            doRealUpload(videoItem);
                        }
                    }
                });
            }
        };

        if (!NetworkUtil.isWifi(this)) {
            EasyAlertDialogHelper.createOkCancelDiolag(this, null, getString(R.string.wifi_confirm),
                    getString(R.string.yes), getString(R.string.no), false, listener).show();
            return;
        }

        doRealUpload(videoItem);
    }

    /**
     * 调用上传接口，上传视频
     */
    private void doRealUpload(VideoItem videoItem) {
        videoItem.setState(UploadState.STATE_WAIT);
        List<VideoItem> videoItems = new ArrayList<>(1);
        videoItems.add(videoItem);
        uploadController.getDataAccessor().addLocalVideoItems(videoItems);
    }

    private int getItemIndex(String id) {
        for (int i = 0; i < items.size(); i++) {
            VideoItem videoItem = items.get(i);
            if (TextUtils.equals(videoItem.getId(), id)) {
                return i;
            }
        }

        return -1;
    }

    /**
     * ************************ Upload ui ************************
     */
    @Override
    public void updateAllItems() {

    }

    @Override
    public void updateUploadState(int state) {
        if (state == UploadState.STATE_UPLOAD_COMPLETE) {
            videoCount++;
        }
    }

    @Override
    public void updateItemProgress(String id, int progress, int state) {
        int index = getItemIndex(id);
        if (index >= 0) {
            videoAdapter.putProgress(id, progress);
            videoAdapter.notifyDataItemChanged(index);
        }
    }

    @Override
    public Context getContext() {
        return this;
    }

    @Override
    public void showLoading(boolean show) {

    }

    @Override
    public void onDataSetChanged(List<VideoItem> data) {
        for (VideoItem item : data) {
            if (items.contains(item)) {
                continue;
            }
            items.add(0, item);
        }
        videoAdapter.notifyDataSetChanged();
    }

    @Override
    public boolean isUiInit() {
        return false;
    }

    @Override
    public void onAddVideoResult(int code, String id, AddVideoResponseEntity addVideoResponseEntity) {
        if (code == 200) {
            int index = getItemIndex(id);
            if (index >= 0 && index < items.size() && items.get(index) != null) {
                VideoItem videoItem = items.get(index);
                videoItem.setVid(addVideoResponseEntity.getVid());
                VideoInfoEntity infoEntity = new VideoInfoEntity();
                infoEntity.setVid(addVideoResponseEntity.getVid());
                infoEntity.setUpdateTime(addVideoResponseEntity.getUpdateTime());
                infoEntity.setSnapshotUrl(addVideoResponseEntity.getSnapshotUrl());
                infoEntity.setOrigUrl(addVideoResponseEntity.getOrigUrl());
                infoEntity.setCreateTime(addVideoResponseEntity.getCreateTime());
                infoEntity.setCompleteTime(addVideoResponseEntity.getCompleteTime());
                videoItem.setEntity(infoEntity);
            }
            videoAdapter.notifyDataItemChanged(index);
        }
    }

    /**
     * ************************ Upload ui end ************************
     */

    /**
     * ************************ adapter listener *********************
     */

    @Override
    public void onRetryUpload(VideoItem videoItem) {
        uploadFile(videoItem);
    }

    @Override
    public void onVideoDeleted(int position, VideoItem videoItem) {
        showDeleteConfirm(position, videoItem);
    }

    private void showDeleteConfirm(final int position, final VideoItem videoItem) {
        EasyAlertDialogHelper.OnDialogActionListener listener = new EasyAlertDialogHelper.OnDialogActionListener() {

            @Override
            public void doCancelAction() {
            }

            @Override
            public void doOkAction() {
                showNetworkDialog(position, videoItem);
            }
        };

        final EasyAlertDialog dialog = EasyAlertDialogHelper.createOkCancelDiolag(this, null,
                getString(R.string.delete_confirm_tip), false, listener);
        dialog.show();
    }

    private void showNetworkDialog(int position, VideoItem videoItem) {
        if (NetworkUtil.isNetAvailable(this)) {
            doRealDelete(position, videoItem);
        } else {
            EasyAlertDialogHelper.showOneButtonDiolag(this, null, getString(R.string.network_is_not_available),
                    getString(R.string.iknow), true, null);
        }
    }

    private void doRealDelete(final int position, VideoItem videoItem) {
        if (videoItem.getEntity() == null || videoItem.getEntity().getVid() == 0) {
            return;
        }
        DemoServerHttpClient.getInstance().videoDelete(videoItem.getEntity().getVid(), null, new DemoServerHttpClient.DemoServerHttpCallback<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                videoCount--;
                videoAdapter.remove(position);
                videoAdapter.notifyDataSetChanged();
            }

            @Override
            public void onFailed(int code, String errorMsg) {

            }
        });
    }

    // 长按
    private void onNormalLongClick(final int position) {
        CustomAlertDialog alertDialog = new CustomAlertDialog(this);
        alertDialog.setCancelable(true);
        alertDialog.setCanceledOnTouchOutside(true);

        alertDialog.addItem(getString(R.string.delete), new CustomAlertDialog.onSeparateItemClickListener() {

            @Override
            public void onClick() {
                doRealDelete(position, videoAdapter.getItem(position));
            }
        });
        alertDialog.show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case VideoShootActivity.REQUEST_CODE:
                    VideoItem videoItem = (VideoItem) data.getSerializableExtra(VideoShootActivity.EXTRA_VIDEO_ITEM);
                    uploadFile(videoItem);
                    break;
            }
        }
    }
}
